#include <func.h>

#define MAX_MAP_SIZE 10 * 4096  // 虚拟内存一页的大小一般是 4096 字节

int main(int argc, char* argv[])
{
    if(argc != 3)
        error(1, 0, "Usage: %s src dst", argv[0]);

    int src_fd = open(argv[1], O_RDONLY);
    if(src_fd == -1)
        error(1, errno, "open %s failed", argv[1]);
    int dst_fd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0666);
    if(dst_fd == -1)
        error(1, errno, "open %s failed", argv[2]);

    struct stat statbuf;
    if(fstat(src_fd, &statbuf) == -1)
        error(1, errno, "fstat");

    off_t size = statbuf.st_size; // src文件的大小

    if(ftruncate(dst_fd, size) == -1)
        error(1, errno, "ftruncate");

    off_t start = 0;  // 偏移量
    off_t length = MAX_MAP_SIZE;
    
    while(start < size)
    {
        if(size - start < MAX_MAP_SIZE)
            length = size - start;
        void* src_m = mmap(NULL, length, PROT_READ, MAP_SHARED, src_fd, start);
        if(src_m == MAP_FAILED)
            error(1, errno, "mmap");
        void* dst_m = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, dst_fd, start);
        if(dst_m == MAP_FAILED)
            error(1, errno, "mmap");

        memcpy(dst_m, src_m, length);

        if(munmap(src_m, length) == -1)
            error(1, errno, "munmap");
        if(munmap(dst_m, length) == -1)
            error(1, errno, "munmap");
        start += length; 
    }

    close(src_fd);
    close(dst_fd);

    return 0;
}

